package cn.elwy.rcp.ui.table.event;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.widgets.Widget;

/**
 * @description
 * @create 2011-1-17 下午10:16:47
 * @author tianlh
 */
public final class EventManager {

  private static final Map<String, List<PropertyChangeListener>> LISTENER_MAP = new HashMap<String, List<PropertyChangeListener>>();

  public static synchronized void registListener(String property, PropertyChangeListener listener) {
    List<PropertyChangeListener> listeners = LISTENER_MAP.get(property);
    if (listeners == null) {
      listeners = new ArrayList<PropertyChangeListener>();
      LISTENER_MAP.put(property, listeners);
    }
    if (listener != null && !listeners.contains(listener)) {
      listeners.add(listener);
    }
  }

  public static synchronized void registListener(PropertyChangeListener listener, String... properties) {
    for (String property : properties) {
      registListener(property, listener);
    }
  }

  public static synchronized void unregistListener(String property, PropertyChangeListener listener) {
    List<PropertyChangeListener> listeners = LISTENER_MAP.get(property);
    if (listeners != null) {
      listeners.remove(listener);
    }
  }

  public static synchronized void unregistListener(String property, PropertyChangeListener... listeners) {
    for (PropertyChangeListener listener : listeners) {
      unregistListener(property, listener);
    }
  }

  public static synchronized void unregistListener(PropertyChangeListener listener, String... properties) {
    for (String property : properties) {
      unregistListener(property, listener);
    }
  }

  public static synchronized void unregistListener(PropertyChangeListener listener) {
    Set<String> propertys = LISTENER_MAP.keySet();
    for (String property : propertys) {
      unregistListener(property, listener);
    }
  }

  public static synchronized void unregistListenerAtWidgetDispose(PropertyChangeListener listener, Widget widget) {
    widget.addDisposeListener(new WidgetDepositListener(listener));
  }

  public static synchronized void firePropertyChange(String property, Object oldValue, Object newValue) {
    firePropertyChange(new PropertyChangeEvent(EventManager.class, property, oldValue, newValue));
  }

  public static synchronized void firePropertyChange(PropertyChangeEvent event) {
    List<PropertyChangeListener> listeners = LISTENER_MAP.get(event.getPropertyName());
    if (listeners != null) {
      for (PropertyChangeListener listener : listeners) {
        listener.propertyChange(event);
      }
    }
  }

  private static class WidgetDepositListener implements DisposeListener {

    private final PropertyChangeListener listener;

    public WidgetDepositListener(PropertyChangeListener listener) {
      this.listener = listener;
    }

    @Override
    public void widgetDisposed(DisposeEvent e) {
      unregistListener(listener);
    }
  }
}
